/*Author: Rony Lahav (ID:043489889)*/

import java.util.Collection;
import java.util.TreeMap;

/**
 * This class manages the IM messages by sending an IM message to all online peers
 */
public class IMManager {
	
	private static IMManager imm;
	
	//singletone
	private IMManager(){
	}
	
	public static IMManager getInstance(){
		if (imm==null)
			imm=new IMManager();
		return imm;
	}
	
	/*gets all online peers, creates an IM message and sends it to them*/
	public void sendIMToPeers(String msg, String originPeerID) {
		if (!final_project.isShutDown()){
			// Get from the DB all of the tuples to which I should send IM to
			TreeMap<String,DBTuple> peersToSendIM = (TreeMap<String,DBTuple>)DataBase.getInstance().getAllOnlineRegTuples();
			//run over all peers and send an IM message
			Collection<DBTuple> c = peersToSendIM.values();
			String IMmsg="";
			if (c.size()>0){	//at least one online peer
				IMmsg=createIMMessage(msg);
			}
			for (DBTuple tuple : c) {
				if (final_project.isShutDown()) {
					break;
				}
				// Open a dedicated thread to send IM to the specific peer besides originating message peer
				if (tuple.getPeerID() == null || !tuple.getPeerID().equals(originPeerID)){
					sendIMToOneTuple(tuple, IMmsg);
				}
			}
		}
	}
	
	public void sendIMToSN(String msg) {
		if (!final_project.isShutDown() && !final_project.inFallBackMode){
			// Get main SN
			DBTuple snTuple = final_project.getMyMainSN();
			//send an FT message
			String IMmsg="";
			if (snTuple!=null && snTuple.getStatus()){	//SN is online
				IMmsg=createIMMessage(msg);
				sendIMToOneTuple(snTuple, IMmsg);
			}
		}
	}
	
	/**
	 * create IM message in correct format
	 * @return IM message
	 */
	public String createIMMessage(String msg) {
		String message = MessageCenter.getInstance().createMessage_IM(msg);
		return message;
	}
	
	public void sendIMToAllSNs(String msg, String originSNKey) {
		if (!final_project.isShutDown()){
			String IMmsg=createIMMessage(msg);
			SNsHandler.getInstance().propagateMessageToMySNs(IMmsg, originSNKey);
		}
	}
	
	protected void sendIMToOneTuple(DBTuple tuple, String IMmsg){
		// Open a dedicated thread to send FT to one specific peer
		SingleUDPMessageSender singleIM = new SingleUDPMessageSender(final_project.mainUDPSoc, tuple, IMmsg, final_project.getNewUniqueID());
		Thread thread = new Thread(singleIM);
		final_project.addThreadToLivingList(singleIM.getUniqueID(), thread);
		thread.start();
	}
}
